package vn.wallet.app.helper;

import java.io.File;
import java.security.MessageDigest;
import java.text.MessageFormat;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;

import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
import javax.faces.component.UIInput;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;

public class AppUtils {

	public static final String USER_LOGINED_SESSION_NAME = "user";
	public static final String LOGIN_URL = "login.htm";
	public static final String LOGINED_SUCCESS_URL = "app/index.htm";

	private static final Logger log = Logger.getLogger(AppUtils.class);

	public static String getRequestIp() {
		HttpServletRequest request = (HttpServletRequest) FacesContext
				.getCurrentInstance().getExternalContext().getRequest();

		return request.getRemoteAddr();
	}

	public static Map<String, String> getParamsMap() {
		return FacesContext.getCurrentInstance().getExternalContext()
				.getRequestParameterMap();
	}

	public static String getRequestParamValue(String param) throws Exception {
		try {
			String val = "";
			Map<String, String> mapParams = getParamsMap();
			val = mapParams.get(param);

			return val;
		} catch (Exception ex) {
			throw ex;
		}
	}

	public static void setRequestParam(String key, Object obj) throws Exception {
		try {
			getParamsMap().put(key, obj.toString());
		} catch (Exception ex) {
			throw ex;
		}
	}

	public static void listRequestParams() {
		Map<String, String> mParams = getParamsMap();
		Set<String> key = mParams.keySet();
		System.out.println("listRequestParams");
		for (String s : key) {
			System.out.println("\t" + s + ": " + mParams.get(s));
		}
	}

	public static String removeStringArrayPart(String strArray, String strPart,
			String sep) throws Exception {
		String strFinal = "";

		try {
			for (String str : strArray.split(sep)) {
				if (!str.equals(strPart)) {
					strFinal += sep + str;
				}
			}
			if (!strFinal.isEmpty()) {
				strFinal = strFinal.substring(1);
			}
			return strFinal;
		} catch (Exception ex) {
			throw ex;
		}
	}

	/**
	 * Return cleaned String with<br/>
	 * &nbsp;&nbsp;&nbsp;&nbsp;<b>no duplicate separate string</b><br/>
	 * &nbsp;&nbsp;&nbsp;&nbsp;<b>no separate at beginning of string</b><br/>
	 * &nbsp;&nbsp;&nbsp;&nbsp;<b>no separate at ending of string</b><br/>
	 * <br/>
	 * 
	 * @param strArray
	 * @param sep
	 * @return cleaned String
	 * @throws Exception
	 */
	public static String cleanRedundantString(String strArray, String sep)
			throws Exception {
		try {
			strArray = strArray.replaceAll("(" + sep + ")\\1+", sep);
			if (strArray.indexOf(sep) == 0) {
				strArray = strArray.substring(1);
			}
			if (strArray.indexOf(sep) == strArray.length() - 1) {
				strArray = strArray.substring(0, strArray.length() - 1);
			}
			return strArray;
		} catch (Exception ex) {
			throw ex;
		}
	}

	/**
	 * Returns the clientId for a component with id="foo"
	 */
	public static String getClientId(String componentId) throws Exception {
		try {
			FacesContext context = FacesContext.getCurrentInstance();
			UIViewRoot root = context.getViewRoot();

			UIComponent c = findComponent(root, componentId);
			return c.getClientId(context);
		} catch (Exception ex) {
			throw ex;
		}
	}

	/**
	 * Finds component with the given id
	 */
	public static UIComponent findComponent(UIComponent c, String id) {
		if (id.equals(c.getId())) {
			return c;
		}
		Iterator<UIComponent> kids = c.getFacetsAndChildren();
		while (kids.hasNext()) {
			UIComponent found = findComponent(kids.next(), id);
			if (found != null) {
				return found;
			}
		}
		return null;
	}

	/**
	 * return value base on resource key
	 * 
	 * @param resKey
	 *            : resource key
	 * @return
	 */
	public static String getResource(String resKey) {
		String str = "";
		try {
			FacesContext context = FacesContext.getCurrentInstance();
			ResourceBundle bundle = context.getApplication().getResourceBundle(
					context, "msg");

			str = bundle.getString(resKey);
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
		return str;
	}

	/**
	 * return value base on resource key and parameters
	 * 
	 * @param resKey
	 *            : resource key
	 * @param params
	 *            : accept 1 or arrayObject
	 * @return
	 */
	public static String getResource(String resKey, String... params) {
		String str = "";
		try {
			str = getResource(resKey);
			MessageFormat msgFormat = new MessageFormat(str);
			str = msgFormat.format(params);
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
		return str;
	}

	public static void createFolderSequence(String folders, String path) {
		String folder[] = folders.split("//");
		String lastFolder = "";
		for (String child : folder) {
			if (child.isEmpty()) {
				continue;
			}

			File f = new File(path + "//" + lastFolder + "//" + child);
			if (!f.exists()) {
				f.mkdir();
				System.out.println("created folder:  " + f.getAbsolutePath());
			}
			lastFolder += child + "//";
		}
	}

	public void resetUIForm(UIComponent comp) {
		UIComponent parent = comp.getParent();
		if (parent instanceof UIForm) {
			resetUIFields(parent);
		} else if (parent != null) {
			resetUIForm(comp);
		} else {
			resetUIFields(parent);
		}
	}

	public void resetUIFields(UIComponent comp) {
		for (UIComponent child : comp.getChildren()) {
			if (child.getChildCount() > 0) {
				resetUIFields(child);
			}
			if (child instanceof UIInput) {
				((UIInput) child).resetValue();
			}
		}
	}

	public static String encryptPassword(String password) {
		String str = "";
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-256");
			md.update(password.getBytes());

			byte byteData[] = md.digest();

			// convert the byte to hex format method 1
			StringBuffer sb = new StringBuffer();
			for (byte element : byteData) {
				sb.append(Integer.toString((element & 0xff) + 0x100, 16)
						.substring(1));
			}

			str = sb.toString();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return str;
	}
}
